package Beans;

import Bank.*;
import DBConnection.DBAPI;
import org.apache.log4j.Logger;

import javax.annotation.PostConstruct;
import java.math.BigInteger;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

@javax.ejb.Singleton(name = "TransactionProcessorEJB")
public class TransactionProcessorBean implements TransactionProcessorBeanInterface {

    private static final Logger log = Logger.getLogger(TransactionProcessorBean.class);

    public TransactionProcessorBean() {
        setPool(TransactionPool.getInstance());
    }

    private TransactionPoolInterface pool;
    private boolean isFree = true;

    public void setPool(TransactionPoolInterface pool){
        this.pool = pool;
    }

    public void addTransaction(BigInteger id, Account src, Account target, User initiator,
                               double summ, Date date, Transaction.transactionStatus status){
        pool.addTransaction(TransactionFactory.createTransaction(id, src, target, initiator, summ, date, status));
    }

    @PostConstruct
    public void setTimer(){
        Timer timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                tryToDoTransaction();
            }
        };

        timer.schedule(task, 0, 30000);
    }

    public void tryToDoTransaction(){
        if (isFree) {
            isFree = false;
            DoTransactions();
        }
    }

    private void DoTransactions(){
        Transaction tr = pool.getNextTransaction();
        if (tr != null){
            log.info("try to process transaction " + tr.toString());
            DBAPI.updateParam(tr.getId(), DBAPI.ATTR_TRANSACTION_STATUS, Transaction.transactionStatus.inProgress.toString());
            if (tr.getSrc().getAmount() >= tr.getSumm()){
                DBAPI.updateParam(tr.getSrc().getId(), DBAPI.ATTR_AMOUNT, tr.getSrc().getAmount() - tr.getSumm());
                DBAPI.updateParam(tr.getTarget().getId(), DBAPI.ATTR_AMOUNT, tr.getTarget().getAmount() + tr.getSumm());
                DBAPI.updateParam(tr.getId(), DBAPI.ATTR_TRANSACTION_STATUS, Transaction.transactionStatus.success.toString());
                log.info("transaction finish successful");
            } else{
                log.info("transaction failed, not enough money");
                DBAPI.updateParam(tr.getId(), DBAPI.ATTR_TRANSACTION_STATUS, Transaction.transactionStatus.notEnoughMoney);
            }
            isFree = true;
            tryToDoTransaction();
        }
        isFree = true;
    }

}
